﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DirectSell.Common.CodeHelp
{
    public class ValidateCode
    {

        #region 获取随机数字
        /// <summary>
        /// 获取随机数字
        /// </summary>
        /// <param name="len">字符串长度</param>
        /// <returns></returns>
        public static string GetRandNumber(int len)
        {
            string s = "0123456789";
            string str = "";
            Random r = new Random();
            for (int i = 0; i < len; i++)
            {
                str += s.Substring(r.Next(s.Length), 1);
            }
            return str;
        }
        #endregion

        #region 获取随机数
        /// <summary>
        /// 获取随机数
        /// </summary>
        /// <param name="len"></param>
        /// <returns></returns>
        public static string GetRandString(int len)
        {
            //string s = "0123456789";
            string s = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
            string str = "";
            Random r = new Random();
            for (int i = 0; i < len; i++)
            {
                str += s.Substring(r.Next(s.Length), 1);
            }
            return str;
        }
        #endregion

        #region 获取验证码图片
        /// <summary>
        /// 获取验证码图片
        /// </summary>
        /// <param name="checkCode"></param>
        /// <returns></returns>
        public static byte[] CreateCheckCode(string checkCode)
        {
            if (checkCode == null || checkCode.Trim() == String.Empty)
                return null;
            int iWordWidth = 40;
            int iImageWidth = checkCode.Length * iWordWidth;
            Bitmap image = new Bitmap(iImageWidth, 40);
            Graphics g = Graphics.FromImage(image);
            try
            {
                Random rand = new Random();

                //获取随机字符
                string str = checkCode;
                g.InterpolationMode = InterpolationMode.Low;
                g.CompositingQuality = CompositingQuality.HighSpeed;
                g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
                g.SmoothingMode = SmoothingMode.AntiAlias;

                //绘制渐变背景
                Rectangle rect = new Rectangle(0, 0, image.Width, image.Height);
                Brush brushBack = new LinearGradientBrush(rect, Color.FromArgb(rand.Next(150, 256), 255, 255), Color.FromArgb(255, rand.Next(150, 256), 255), rand.Next(90));
                g.FillRectangle(brushBack, rect);

                //绘制干扰曲线
                for (int i = 0; i < 2; i++)
                {
                    Point p1 = new Point(0, rand.Next(image.Height));
                    Point p2 = new Point(rand.Next(image.Width), rand.Next(image.Height));
                    Point p3 = new Point(rand.Next(image.Width), rand.Next(image.Height));
                    Point p4 = new Point(image.Width, rand.Next(image.Height));
                    Point[] p = { p1, p2, p3, p4 };
                    Pen pen = new Pen(Color.Gray, 1);
                    g.DrawBeziers(pen, p);
                }

                //逐个绘制文字
                for (int i = 0; i < str.Length; i++)
                {
                    string strChar = str.Substring(i, 1);
                    int deg = rand.Next(-15, 15);
                    float x = (image.Width / str.Length / 2) + (image.Width / str.Length) * i;
                    float y = image.Height / 2;
                    //随机字体大小
                    Font font = new Font("Consolas", rand.Next(16, 24), FontStyle.Regular);
                    SizeF size = g.MeasureString(strChar, font);
                    Matrix m = new Matrix();
                    //旋转
                    m.RotateAt(deg, new PointF(x, y), MatrixOrder.Append);
                    //扭曲
                    m.Shear(rand.Next(-10, 10) * 0.03f, 0);
                    g.Transform = m;
                    //随机渐变画笔
                    Brush brushPen = new LinearGradientBrush(rect, Color.FromArgb(rand.Next(0, 256), 0, 0), Color.FromArgb(0, 0, rand.Next(0, 256)), rand.Next(90));
                    g.DrawString(str.Substring(i, 1), font, brushPen, new PointF(x - size.Width / 2, y - size.Height / 2));

                    g.Transform = new Matrix();
                }
                g.DrawRectangle(new Pen(Color.Silver), 0, 0, image.Width - 1, image.Height - 1);
                System.IO.MemoryStream ms = new System.IO.MemoryStream();
                image.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
                return ms.ToArray();
            }
            finally
            {
                g.Dispose();
                image.Dispose();
            }
        }
        #endregion

        #region 随机中文
        /// <summary>
        /// 随机中文
        /// </summary>
        /// <returns></returns>
        public static string GenerateCheckCode()
        {
            string checkCode = String.Empty;

            System.Random random = new Random();

            Encoding gb = Encoding.GetEncoding("gb2312");
            //调用函数产生4个随机中文汉字编码 柯乐义
            object[] bytes = CreateRegionCode(20);
            //根据汉字编码的字节数组解码出中文汉字 

            string str1 = gb.GetString((byte[])Convert.ChangeType(bytes[random.Next(0, 19)], typeof(byte[])));
            string str2 = gb.GetString((byte[])Convert.ChangeType(bytes[random.Next(0, 19)], typeof(byte[])));
            string str3 = gb.GetString((byte[])Convert.ChangeType(bytes[random.Next(0, 19)], typeof(byte[])));
           
            //输出的控制台 
            checkCode = str1 + str2 + str3 ;

            return checkCode;

        }


        public static object[] CreateRegionCode(int strlength)
        {
            //定义一个字符串数组储存汉字编码的组成元素 
            string[] rBase = new String[16] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
            Random rnd = new Random();
            //定义一个object数组用来 
            object[] bytes = new object[strlength];

            /*每循环一次产生一个含两个元素的十六进制字节数组，并将其放入bject数组中 
            每个汉字有四个区位码组成 
            区位码第1位和区位码第2位作为字节数组第一个元素 
            区位码第3位和区位码第4位作为字节数组第二个元素 
            */
            for (int i = 0; i < strlength; i++)
            {
                //区位码第1位 
                int r1 = rnd.Next(11, 14);
                string strR1 = rBase[r1].Trim();

                //区位码第2位 
                rnd = new Random(r1 * unchecked((int)DateTime.Now.Ticks) + i);//更换随机数发生器的

                //种子避免产生重复值 
                int r2;
                if (r1 == 13)
                {
                    r2 = rnd.Next(0, 7);
                }
                else
                {
                    r2 = rnd.Next(0, 16);
                }
                string strR2 = rBase[r2].Trim();

                //区位码第3位 
                rnd = new Random(r2 * unchecked((int)DateTime.Now.Ticks) + i);
                int r3 = rnd.Next(10, 16);
                string strR3 = rBase[r3].Trim();

                //区位码第4位 
                rnd = new Random(r3 * unchecked((int)DateTime.Now.Ticks) + i);
                int r4;
                if (r3 == 10)
                {
                    r4 = rnd.Next(1, 16);
                }
                else if (r3 == 15)
                {
                    r4 = rnd.Next(0, 15);
                }
                else
                {
                    r4 = rnd.Next(0, 16);
                }
                string strR4 = rBase[r4].Trim();

                //定义两个字节变量存储产生的随机汉字区位码 keleyi.com
                byte byte1 = Convert.ToByte(strR1 + strR2, 16);
                byte byte2 = Convert.ToByte(strR3 + strR4, 16);
                //将两个字节变量存储在字节数组中 
                byte[] strR = new byte[] { byte1, byte2 };

                //将产生的一个汉字的字节数组放入object数组中 
                bytes.SetValue(strR, i);
            }
            return bytes;
        }
        #endregion

    }
}
